#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

const std::string blank_space_sep = " "; // 有效载荷内部的分隔符
const std::string protocol_sep = "\n";   // 报文与报文之间的分隔符

//"len"\n"123 + 456"\n
std::string Encode(std::string &content) // 将有效载荷封装报头
{
    std::string package;
    size_t len = content.size();
    package += std::to_string(len);
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

//"len"\n"123 + 456"\n  对他进行解析，拿出里面的内容
bool Decode(std::string &package, std::string *content) // 对报文解析，拿到有效载荷
{
    size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    std::string str_len = package.substr(0, pos);
    size_t len = std::stoi(str_len);
    size_t total = str_len.size() + len + 2; // 这个报文的实际长度
    if (package.size() < total)              // 这个报文的本该有的长度
        return false;

    *content = package.substr(pos + 1, len);

    // 有可能会有多个报文，删除前面的报文
    package.erase(0, total);
    return true;
}

class Request
{
public:
    Request(int data1, int data2, char oper)
        : x(data1),
          y(data2),
          op(oper)
    {
    }
    Request()
    {
    }

    // "123 + 456"
    bool Serialization(std::string *content) // 序列化
    {
#ifdef MySer

        *content += std::to_string(x);
        *content += blank_space_sep;
        *content += op;
        *content += blank_space_sep;
        *content += std::to_string(y);
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;

        Json::FastWriter w;
        *content = w.write(root);
        return true;
#endif
    }

    bool Deserialization(std::string &content) // 反序列化
    {
#ifdef MySer
        size_t left = content.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string left_part = content.substr(0, left);

        size_t right = content.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false;
        std::string right_part = content.substr(right + 1);

        if (left + 2 != right)
            return false;
        op = content[left + 1];
        x = std::stoi(left_part);
        y = std::stoi(right_part);
        return true;
#else
        Json::Value v;
        Json::Reader r;
        r.parse(content, v);

        x = v["x"].asInt();
        y = v["y"].asInt();
        op = v["op"].asInt();
        return true;
#endif
    }

public:
    int x;
    int y;
    char op;
};

class Response
{
public:
    Response(int result, int code)
        : _result(result),
          _code(code)
    {
    }
    Response()
    {
    }

    // "result code"
    bool Serialization(std::string *content)
    {
#ifdef MySer

        *content += std::to_string(_result);
        *content += blank_space_sep;
        *content += std::to_string(_code);
        return true;
#else
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::FastWriter w;
        *content = w.write(root);
        return true;
#endif
    }

    bool Deserialization(std::string &content)
    {
#ifdef MySer
        size_t pos = content.find(blank_space_sep);
        if (pos == std::string::npos)
            return false;
        std::string left = content.substr(0, pos);
        std::string right = content.substr(pos + 1);

        _result = std::stoi(left);
        _code = std::stoi(right);
        return true;
#else
        Json::Value v;
        Json::Reader r;
        r.parse(content, v);

        _result = v["result"].asInt();
        _code = v["code"].asInt();
        return true;

#endif
    }

public:
    int _result;
    int _code;
};